package com.ruoyi.common.service;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.BaseAudit;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;




/**
 * 
 * @author Administrator
 *
 * @param <M>
 * @param <T>
 */
public class MyBaseService<M extends BaseMapper<T>, T extends BaseAudit> extends ServiceImpl<BaseMapper<T>, T>{

	
	  /**
     * 设置请求分页数据
     */
	public void startPage(int pageNum,int pageSize){
		 PageHelper.startPage(pageNum, pageSize);
    }

    /**
     * 设置请求排序数据
     */
	public void startOrderBy(String orderBy){
         PageHelper.orderBy(SqlUtil.escapeOrderBySql(orderBy));
    }
	
	/**
	 * 	获取map
	 * @return
	 */
	public Map<String, Object> newMap(){
		return new HashMap<String, Object>();
	}


	/**
	 * 	查询 根据ent id 条件
	 * @param ent
	 * @return
	 */
	public T get(Long id) {
		QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
		queryWrapper.eq("id", id);
		return getOne(queryWrapper);
	}
	
	/**
	 * 	查询一个
	 * @param ar map.put("字段名称","字段值")
	 * @return
	 */
	public T findOne(Map<String, Object> map) {
		return getOne(getQueryWrapperEq(map));
	}
	
	/**
	 * 	查询数量
	 * @param ar map.put("字段名称","字段值")
	 * @return
	 */
	public int findCount(Map<String, Object> map) {
		return count(getQueryWrapperEq(map));
	}
	
	
	/**
	 * 	查询列表
	 * @param ar map.put("字段名称","字段值")
	 * @return
	 */
	public List<T> findList(Map<String, Object> map) {
		return list(getQueryWrapperEq(map));
	}
	 /**
	  * 分页查询
	  * @param map
	  * @param page
	  * @return
	  */
	public PageInfo<T> findPage(Map<String, Object> map,PageDomain page) {
		Integer pageNum = page.getPageNum();
		Integer pageSize = page.getPageSize();
		if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
		{
			String orderBy = SqlUtil.escapeOrderBySql(page.getOrderBy());
			Boolean reasonable = page.getReasonable();
			PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
		}
		return new PageInfo<T>(findList(map));
	}
	
	
	
	/**
	 * 添加
	 */
	public boolean save(T entity) {
		boolean countbool =  super.save(entity) ;
		return countbool;
	}
	
	
	/**
	 *    更新
	 * @param id id
	 * @param ar map.put("字段名称","字段值")
	 * @return
	 */
	public boolean updateById(Long id,Map<String, Object> map) {
		return update(getUpdateWrapperSet(map).eq("id", id));
	}
	
	/**
	 *    更新
	 * @param ids ids
	 * @param ar map.put("字段名称","字段值")
	 * @return
	 */
	public boolean updateByIds(Collection<?> ids,Map<String, Object> map) {
		return update(getUpdateWrapperSet(map).in("id", ids));
	}
	
  
	/**
	 *    更新
	 * @param id id
	 * @param ar "字段名称","字段值"
	 * @return
	 */
	public boolean updateById(Long id,T ent) {
		return updateById(ent);
	}
 
	

	

	
	 
	
	/**
	 * 	获取修改查询条件null值也要更新
	 * @param ent
	 * @return
	 */
	public UpdateWrapper<T> getUpdateWrapperSet(Map<String, Object> map){
		return getUpdateWrapperSet(map,false);
	}
	
	/**
	 * 	获取修改查询条件
	 * @param ent
	 * @param isNullUpdate null值不更新
	 * @return
	 */
	public UpdateWrapper<T> getUpdateWrapperSet(Map<String, Object> map,boolean isNullUpdate){
		UpdateWrapper<T> updateWrapper = new UpdateWrapper<T>();
		if(null != map && !map.isEmpty()){
			Iterator<Map.Entry<String, Object>> itr = map.entrySet().iterator();
			while(itr.hasNext()){
				Map.Entry<String, Object> ent = itr.next();
				if((!isNullUpdate) || ent.getValue()!=null) {
					updateWrapper.set(StringUtils.toUnderScoreCase(ent.getKey()),ent.getValue());
				}
			}
		}
		
		return updateWrapper;
	}

	

	
	/**
	 * 	获取查询条件
	 * @param ent
	 * @return
	 */
	public QueryWrapper<T> getQueryWrapperEq(Map<String, Object> map){
		QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
		if(null != map && !map.isEmpty()){
			Iterator<Map.Entry<String, Object>> itr = map.entrySet().iterator();
			while(itr.hasNext()){
				Map.Entry<String, Object> ent = itr.next();
				queryWrapper.eq(StringUtils.toUnderScoreCase(ent.getKey()),ent.getValue());
			}
		}
		return queryWrapper;
	}
	 
	
	public QueryWrapper<T> getQueryWrapper(Map<String, Object> params,QueryWrapper<T> queryWrapper){
		if(queryWrapper==null) {
			queryWrapper = new QueryWrapper<T>();
		}
		if(null != params && !params.isEmpty()){
			Iterator<Map.Entry<String, Object>> itr = params.entrySet().iterator();
			while(itr.hasNext()){
				Map.Entry<String, Object> ent = itr.next();
				String key = ent.getKey();
				Object val = ent.getValue();
				if(key!=null && key.contains("@")) {
					String[] keys = key.split("@");
					String query = keys[0];
					String column = StringUtils.toUnderScoreCase(keys[1]);
					queryWrapper = setQueryWrapper(queryWrapper, params, query, column, val);
				}

			}
		}
		return queryWrapper;
	}
	
	public QueryWrapper<T>  setQueryWrapper(QueryWrapper<T> queryWrapper,Map<String, Object> params,String query,String column,Object val) {
		if("eq".equals(query)) {
			queryWrapper.eq(StringUtils.toUnderScoreCase(column), val);
		}else if("ne".equals(query)) {
			queryWrapper.ne(StringUtils.toUnderScoreCase(column), val);
		}else if("like".equals(query)) {
			queryWrapper.like(StringUtils.toUnderScoreCase(column), val);
		}else if("notLike".equals(query)) {
			queryWrapper.notLike(StringUtils.toUnderScoreCase(column), val);
		}else if("likeLeft".equals(query)) {
			queryWrapper.likeLeft(StringUtils.toUnderScoreCase(column), val);
		}else if("likeRight".equals(query)) {
			queryWrapper.likeRight(StringUtils.toUnderScoreCase(column), val);
		}else if("gt".equals(query)) {
			queryWrapper.gt(StringUtils.toUnderScoreCase(column), val);
		}else if("lt".equals(query)) {
			queryWrapper.lt(StringUtils.toUnderScoreCase(column), val);
		}else if("ge".equals(query)) {
			queryWrapper.ge(StringUtils.toUnderScoreCase(column), val);
		}else if("le".equals(query)) {
			queryWrapper.le(StringUtils.toUnderScoreCase(column), val);
		}else if("in".equals(query)) {
			queryWrapper.in(StringUtils.toUnderScoreCase(column), StringUtils.str2Set(val+"",","));
		}else if("isNotNull".equals(query)) {
			queryWrapper.isNotNull(column);
		}else if("isNull".equals(query)) {
			queryWrapper.isNull(column);
		}else if("notIn".equals(query)) {
			queryWrapper.notIn(column, StringUtils.str2Set(val+"",","));
		}else if("between".equals(query)) {
			String ks_key = "begin"+StringUtils.captureName(column);
			String js_key = "end"+StringUtils.captureName(column);
			if(params!=null && params.containsKey(ks_key) && params.containsKey(js_key)) {
				queryWrapper.between(StringUtils.toUnderScoreCase(column), params.get(ks_key), params.get(js_key));
			}else if(params!=null && params.containsKey(ks_key)) {
				queryWrapper.ge(StringUtils.toUnderScoreCase(column), params.get(ks_key));
			}else if(params!=null && params.containsKey(js_key)) {
				queryWrapper.le(StringUtils.toUnderScoreCase(column), params.get(js_key));
			}
		} else if("eqorlike".equals(query)) {
			String[] columns = column.split("\\|");
			queryWrapper.and(wrapper->wrapper.eq(StringUtils.toUnderScoreCase(columns[0]), val)
			           .or() 
			           .like(StringUtils.toUnderScoreCase(columns[1]), val));
		}else if("eqoreq".equals(query)) {
			String[] columns = column.split("\\|");
			queryWrapper.and(wrapper->wrapper.eq(StringUtils.toUnderScoreCase(columns[0]), val)
			           .or()
			           .eq(StringUtils.toUnderScoreCase(columns[1]), val));
		}else if("likeorlike".equals(query)) {
			String[] columns = column.split("\\|");
			queryWrapper.and(wrapper->wrapper.like(StringUtils.toUnderScoreCase(columns[0]), val)
			           .or()
			           .like(StringUtils.toUnderScoreCase(columns[1]), val));
		}else if("groupBy".equals(query)) {
			queryWrapper.groupBy(StringUtils.toUnderScoreCase(val.toString()));

		}else if("select".equals(query)) {
			queryWrapper.select(StringUtils.toUnderScoreCase(val.toString()));
		}
		return queryWrapper;
	}
	 

	public  Object getObjectValue(T ent, String fieldName) {
		try {
			return PropertyUtils.getProperty(ent, fieldName);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
        return null;
   }
	
	
}
